package edu.mit.compilers.assembly.x64.basic;

public class X64RegisterFamily {
    private final X64Register register64;
    private final X64Register register32;
    private final X64Register register16;
    private final X64Register register8;


    public X64RegisterFamily(X64Register register64, X64Register register32, X64Register register16, X64Register register8) {
        this.register64 = register64;
        this.register32 = register32;
        this.register16 = register16;
        this.register8 = register8;
    }

    public X64Register getRegister(int bytes) {
        switch (bytes) {
            case 8 : return register64;
            case 4 : return register32;
            case 2 : return register16;
            case 1 : return register8;
            default:
                assert false : "not support this bytes " + bytes;
                return null;
        }
    }

    public static X64Register getRegister(String leader, int bytes) {
        switch (leader) {
            case "rax"  :   return RAX_FAMILY.getRegister(bytes);
            case "rbx"  :   return RBX_FAMILY.getRegister(bytes);
            case "rcx"  :   return RCX_FAMILY.getRegister(bytes);
            case "rdx"  :   return RDX_FAMILY.getRegister(bytes);
            case "rsi"  :   return RSI_FAMILY.getRegister(bytes);
            case "rdi"  :   return RDI_FAMILY.getRegister(bytes);
            case "rbp"  :   return RBP_FAMILY.getRegister(bytes);
            case "rsp"  :   return RSP_FAMILY.getRegister(bytes);
            case "r8"   :   return R8_FAMILY.getRegister(bytes);
            case "r9"   :   return R9_FAMILY.getRegister(bytes);
            case "r10"  :   return R10_FAMILY.getRegister(bytes);
            case "r11"  :   return R11_FAMILY.getRegister(bytes);
            case "r12"  :   return R12_FAMILY.getRegister(bytes);
            case "r13"  :   return R13_FAMILY.getRegister(bytes);
            case "r14"  :   return R14_FAMILY.getRegister(bytes);
            case "r15"  :   return R15_FAMILY.getRegister(bytes);
            default:
                assert false : "not support this leader register : " + leader;
                return null;
        }
    }

    public static final X64RegisterFamily RAX_FAMILY = new X64RegisterFamily(X64Register.RAX, null, null, X64Register.AL);
    public static final X64RegisterFamily RBX_FAMILY = new X64RegisterFamily(X64Register.RBX, null, null, X64Register.BL);
    public static final X64RegisterFamily RCX_FAMILY = new X64RegisterFamily(X64Register.RCX, null, null, X64Register.CL);
    public static final X64RegisterFamily RDX_FAMILY = new X64RegisterFamily(X64Register.RDX, null, null, X64Register.DL);
    public static final X64RegisterFamily RSI_FAMILY = new X64RegisterFamily(X64Register.RSI, null, null, X64Register.SIL);
    public static final X64RegisterFamily RDI_FAMILY = new X64RegisterFamily(X64Register.RDI, null, null, X64Register.DIL);
    public static final X64RegisterFamily RBP_FAMILY = new X64RegisterFamily(X64Register.RBP, null, null, X64Register.BPL);
    public static final X64RegisterFamily RSP_FAMILY = new X64RegisterFamily(X64Register.RSP, null, null, X64Register.SPL);
    public static final X64RegisterFamily R8_FAMILY  = new X64RegisterFamily(X64Register.R8, null, null, X64Register.R8B);
    public static final X64RegisterFamily R9_FAMILY  = new X64RegisterFamily(X64Register.R9, null, null, X64Register.R9B);
    public static final X64RegisterFamily R10_FAMILY = new X64RegisterFamily(X64Register.R10, null, null, X64Register.R10B);
    public static final X64RegisterFamily R11_FAMILY = new X64RegisterFamily(X64Register.R11, null, null, X64Register.R11B);
    public static final X64RegisterFamily R12_FAMILY = new X64RegisterFamily(X64Register.R12, null, null, X64Register.R12B);
    public static final X64RegisterFamily R13_FAMILY = new X64RegisterFamily(X64Register.R13, null, null, X64Register.R13B);
    public static final X64RegisterFamily R14_FAMILY = new X64RegisterFamily(X64Register.R14, null, null, X64Register.R14B);
    public static final X64RegisterFamily R15_FAMILY = new X64RegisterFamily(X64Register.R15, null, null, X64Register.R15B);


}
